home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 21
/
Cream of the Crop 21 (Terry Blount) (October 1996).iso
/
os2
/
freetype.zip
/
tttables.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1996-09-07
|
10KB
|
494 lines
Unit TTTables;
interface
uses TTTypes, TTVars, TTCalc;
type
(* "loca" : table of glyph index *)
TLoca = Record
Size : word;
Table : PStorage;
end;
TLocas = array[0..1000] of TLoca;
var
Table_Dir : TTableDir;
Table_Dir_Entries : PTableDirEntries;
Num_TDE : int;
MaxProfile : TMaxProfile;
Font_Header : ^THeader;
Glyph_Locations : ^TLoca;
Glyphs : ^TGlyphs;
Num_Glyphs : int; (* Number of glyphs in current font file *)
function Open_TrueType_File( AName : String ) : boolean;
procedure Close_TrueType_File;
function Load_TrueType_Tables : boolean;
function LookUp_TrueType_Table( ATag : string ) : int;
function Load_TrueType_Header : boolean;
function Load_TrueType_CVT : boolean;
function Load_TrueType_Locations : Boolean;
function Load_TrueType_MaxProfile : boolean;
function Load_TrueType_Glyphs : integer;
implementation
uses TTFile;
(*************************)
(* Load_TrueType_Tables *)
(*************************)
function Load_TrueType_Tables : Boolean;
var
T : LongInt;
L : LongInt;
begin
Load_TrueType_Tables := False;
if not Read_At_Font_File( 0, Table_Dir, sizeof(Table_Dir) ) then exit;
Do32( Fixed( Table_Dir.Version ) );
Do16( Table_Dir.NumTables );
{$IFDEF DEBUG}
Writeln('Version de répertoire : ',TableDir.version/$10000);
Writeln('Nombre de Tables : ',TableDir.numTables);
{$ENDIF}
Num_TDE := Table_Dir.NumTables;
L := sizeof(TTableDirEntry) * Num_TDE;
if not Alloc( L, Pointer(Table_Dir_Entries) ) or
not Read_Font_File( Table_Dir_Entries^, L ) then exit;
for t:=0 to Num_TDE-1 do with Table_Dir_Entries^[t] do
begin
CheckSum:=0;
Do32( Offset );
Do32( Length );
end;
Load_TrueType_Tables := True;
end;
(***************************)
(* LookUp_TrueType_Table *)
(***************************)
function LookUp_TrueType_Table( ATag : string ) : int;
var
TAG : String[4];
i : int;
begin
TAG[0] := #4;
LookUp_TrueType_Table := -1;
if Table_Dir_Entries = nil then exit;
for i := 0 to Num_TDE-1 do
begin
move( Table_Dir_Entries^[i].Tag, Tag[1], 4 );
if Tag = ATag then
begin
LookUp_TrueType_Table := i;
exit;
end
end
end;
(**************************)
(* Load_TrueType_Header *)
(**************************)
function Load_TrueType_Header : Boolean;
var
i : int;
begin
Load_TrueType_Header := False;
i := LookUp_TrueType_Table('head');
if i <= 0 then exit;
if not Alloc( sizeof(THeader), Pointer(Font_Header) ) or
not Read_At_FOnt_File( Table_Dir_Entries^[i].Offset,
Font_Header^, sizeof(THeader) )
then exit;
with Font_Header^ do
begin
Do16( word(IndexToLocFormat) );
Do16( UnitsPerEM );
{$IFDEF DEBUG}
Writeln('Taille du Cadratin : ',UnitsPerEM );
Writeln('IndexToLocFormat : ',IndexToLocFormat );
Writeln('Nombre de glyphes : ',numGlyphs );
{$ENDIF}
end;
Load_TrueType_Header := True;
end;
(***************************)
(* Load_TrueType_Locations *)
(***************************)
function Load_TrueType_Locations : Boolean;
var
i : int;
sz : longint;
t : int;
LongOffsets : int;
locs : PStorage;
locs2 : PShortArray;
Mrk : TMarkRecord;
begin
Load_TrueType_Locations := False;
LongOffsets := 0;
if Font_Header = nil then
if not Load_TrueType_Header then exit;
LongOffsets := Font_Header^.IndexToLocFormat;
(* default offsets format is short *)
T := LookUp_TrueType_Table('loca');
if T < 0 then exit;
if not Alloc( sizeof(TLoca), Pointer(Glyph_Locations) ) then exit;
if LongOffsets <> 0 then
begin
sz := Table_Dir_Entries^[T].Length shr 2;
Glyph_Locations^.Size := sz;
{$IFDEF DEBUG}
Writeln('Glyph Slots # ( 32-bits offsets ) : ', sz );
{$ENDIF}
if not Alloc( 4*Sz, Pointer( Locs ) ) then exit;
Glyph_Locations^.Table := locs;
if not Read_At_Font_File( Table_Dir_Entries^[T].Offset,
Locs^[0], Sz*4 ) then exit;
Do32s( locs^[0], sz );
end
else
begin
sz := Table_Dir_Entries^[T].Length shr 1;
Glyph_Locations^.Size := Sz;
{$IFDEF DEBUG}
Writeln('Glyph Slots # ( 16-bits offsets ) : ', Sz );
{$ENDIF}
if not Alloc( 4*Sz, Pointer(locs) ) then exit;
Mark( Mrk );
if not Alloc( 2*Sz, Pointer(locs2) ) then exit;
Glyph_Locations^.Table := locs;
if not Read_At_Font_File( Table_Dir_Entries^[T].Offset,
locs2^[0], 2*sz ) then exit;
Do16s( locs2^[0], sz );
for i := 0 to sz-1 do Locs^[i] := 2*longint( locs2^[i] );
if not Release( Mrk ) then exit;
end;
Load_TrueType_Locations := True;
end;
function Load_TrueType_CVT : boolean;
var
m : int;
begin
Load_TrueType_CVT := False;
m := LookUp_TrueType_Table('cvt ');
if m<0 then exit;
with Table_Dir_Entries^[m] do
begin
GetMem( CVT, Length );
CvtSize := Length div sizeof(Short);
if not Read_At_Font_File( Offset, CVT^, Length ) then exit;
Do16s( CVT^, CvtSize );
end;
Load_TrueType_CVT := True;
end;
(******************************)
(* Load_TrueType_MaxProfile *)
(******************************)
function Load_TrueType_MaxProfile : boolean;
var
m : int;
begin
Load_TrueType_MaxProfile := False;
m:=LookUp_TrueType_Table('maxp');
if m<0 then exit;
if not Read_At_Font_File( Table_Dir_Entries^[m].Offset,
MaxProfile, sizeof(MaxProfile) ) then exit;
with MaxProfile do
begin
Do32( Version );
Do16( numGlyphs );
Do16( maxPoints );
Do16( maxContours );
Do16( maxCompositePoints );
Do16( maxCompositeContours );
Do16( maxZones );
Do16( maxTwilightPoints );
Do16( maxStorage );
Do16( maxFunctionDefs );
Do16( maxInstructionDefs );
Do16( maxStackElements );
Do16( maxSizeOfInstructions );
Do16( maxComponentElements );
Do16( maxCOmponentDepth );
end;
Num_Glyphs := MaxProfile.NumGlyphs;
Load_TrueType_MaxProfile := True;
end;
(**************************)
(* Load_TrueType_Glyphs *)
(**************************)
function Load_TrueType_Glyphs : integer;
var
sz, szc, szp : int;
i, j, k, cnt : int;
b, c : byte;
offset : longint;
locs : PStorage;
GL : TGlyph;
Con : PGlyphContours;
Pts : PPoints;
label
Suite,
Fin;
begin
Load_TrueType_Glyphs:=0;
i:=LookUp_TrueType_Table('glyf');
if i<0 then exit;
Offset:=Table_Dir_Entries^[i].Offset;
if Glyph_Locations=NIL then
if not Load_TrueType_Locations then exit;
locs := Glyph_Locations^.Table;
sz := Glyph_Locations^.Size;
if not Alloc( Sizeof( TGlyph)*Sz, Pointer(Glyphs) ) then exit;
j:=0;
for i:=0 to Num_Glyphs-1 do
begin
if not Read_At_Font_File( Offset+locs^[i],
GL, 5*sizeof(Integer) ) then goto Suite;
(* INVALID OFFSET ??? *)
Do16( Word( Gl.numberOfContours ) );
Do16( Word( Gl.xMin ) ); Do16( Word( Gl.yMin ) );
Do16( Word( Gl.xMax ) ); Do16( Word( Gl.yMax ) );
Write('.');
{$IFDEF DEBUG}
Writeln(' Nombre de Contours : ',Gl.numberOfContours );
Writeln(' xMin : ',Gl.xMin:4,' xMax : ',Gl.xMax);
Writeln(' yMin : ',Gl.yMin:4,' yMax : ',Gl.yMax);
Writeln('-');
{$ENDIF}
szc:=Gl.numberOfContours;
if szc<0 then Goto Suite;
if szc>MaxProfile.maxContours then
begin
{$IFDEF DEBUG}
Writeln('Erreur: Glyph ',i,' de ',szc,' contours > ',
maxProfile.maxContours );
readkey;
{$ENDIF}
goto Suite;
end;
GetMem( Con, Sizeof(TGlyphContour)*szc );
If Con=NIL then Goto Fin;
Gl.Contours:=Con;
Szp:=0;
For k:=0 to szc-1 do
begin
{$IFDEF DEBUG}
Write( szp,' ');
{$ENDIF}
Con^[k].Start:=Szp;